package cn.hxth.cloud.provider.service.impl;


import cn.hxth.cloud.api.common.constant.OrderInfoStatus;
import cn.hxth.cloud.api.common.util.AbstractBaseServiceImpl;
import cn.hxth.cloud.api.common.util.DateProvider;
import cn.hxth.cloud.api.domain.*;
import cn.hxth.cloud.api.mapper.CompanyMapper;
import cn.hxth.cloud.api.mapper.OrderInfoItemMapper;
import cn.hxth.cloud.api.mapper.OrderInfoMapper;
import cn.hxth.cloud.api.mapper.ProductMapper;
import cn.hxth.cloud.api.rabbitmq.RabbitMQSender;
import cn.hxth.cloud.provider.builder.ProductionOrderBuilder;
import cn.hxth.cloud.provider.factory.ProductionOrderBuilderFactory;
import cn.hxth.cloud.provider.service.OrderService;
import com.alibaba.fastjson.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl extends AbstractBaseServiceImpl implements OrderService  {
    private Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class) ;
    @Autowired
    private CompanyMapper companyMapper ;
    @Autowired
    private OrderInfoMapper orderInfoMapper ;
    @Autowired
    private OrderInfoItemMapper orderInfoItemMapper ;
    @Autowired
    private ProductMapper productMapper ;
    @Autowired
    private ProductionOrderBuilderFactory productionOrderBuilderFactory ;
    @Autowired
    public OrderServiceImpl(RabbitMQSender rabbitMQSender, RedisTemplate<String, String> redisTemplate, DateProvider dateProvider) {
        super(rabbitMQSender, redisTemplate,dateProvider);
    }

    @Override
    public Boolean insertOrder(OrderInfo orderInfo,String mid) {
        try{
            Company company = this.companyMapper.selectByPrimaryKey(orderInfo.getCid()) ; // 查询出需方信息
            orderInfo.setOrderDate(dateProvider.getCurrentTime());
            orderInfo.setCompany(company); // 设置需方信息
            this.orderInfoMapper.insertSelective(orderInfo) ; // 添加订单信息
            ProductOutputOrder productOutputOrder  = null ; // 声明出库变量
            List<ProductionOrder> productionOrders = null ; // 声明生产单集合
              List<ProductOutputOrderItem> productOutputOrderItems= new ArrayList<>() ; // 声明出库单条目集合
            orderInfo.setOrderDate(dateProvider.getCurrentTime()); // 设置下单时间
            List<OrderInfoItem> items = orderInfo.getItems(); // 获取订单条目
            for (OrderInfoItem item:items) { // 遍历订单条目
                item.setOid(orderInfo.getId());  // 为订单条目设置订单ID
              //  item.setOrderInfo(orderInfo);
                Product product = this.productMapper.selectByPrimaryKey(item.getPid()); // 查询相关商品信息
                // 构造出库单条目
                ProductOutputOrderItem productOutputOrderItem = new ProductOutputOrderItem() ;
                productOutputOrderItem.setPid(product.getId()); // 为出库条目设置商品ID
                productOutputOrderItem.setCount(item.getCount()); // 为出库单条目设置出库数量
                productOutputOrderItem.setProduct(product); // 设置所购商品对象
                productOutputOrderItems.add(productOutputOrderItem) ; // 把出库条目加入集合
                if(item.getCount()> product.getInventory() - product.getLockedInventory()){ // 如果该条目订货量大于可售库存 则实例化生产单集合
                    if(productionOrders == null) {
                        orderInfo.setStatus(OrderInfoStatus.PRODUCING);
                        this.updateStatus(orderInfo) ; // 将订单状态设置为正在生产状态
                        productionOrders = new ArrayList<>() ;
                    }
                        ProductionOrderBuilder builder = productionOrderBuilderFactory.getProductionOrderBuilder(); //获取生产单构造器
                        ProductionOrder productionOrder =
                                builder.initProductionOrder().
                                setOrderInfoProperties(orderInfo).
                                setOrderItemsProperties(item).
                                setProductProperties(product).
                                create();
                        productionOrders.add(productionOrder) ; // 构造生产单

                }
                // 如果库存满足订货量实例化出库单条目
                else{
                    System.out.println("wwww");


                }



            }
            this.orderInfoItemMapper.insertList(items) ;
            if(productionOrders == null){ // 循环完毕生，产单集合为空则没有要生产商品
                productOutputOrder  = new ProductOutputOrder() ;
                    orderInfo.setStatus(OrderInfoStatus.DELIVERED); // 将订单改为发货状态
                    this.updateStatus(orderInfo) ;
                productOutputOrder.setProductOutputOrderItems(productOutputOrderItems);
                productOutputOrder.setMakeDate(dateProvider.getCurrentTime());
                productOutputOrder.setOrderInfo(orderInfo);
                productOutputOrder.setOid(orderInfo.getId());
                productOutputOrder.setOrderInfo(orderInfo);
                super.sendMessage("wms",productOutputOrder,"insertProductOutputOrder",mid); // 发送添加出库单消息

            }
            // 如果有需要生产的商品，则发送添加生产单消息
            else {

                super.sendMessage("production",productionOrders,"insertProductionOrder",mid);

                    redisTemplate.opsForValue().set("productOutputOrder_"+orderInfo.getId(), JSONArray.toJSONString(productOutputOrderItems));

                // 锁定相应的订货量库存

                super.sendMessage("inventory",orderInfo,"updateProductInventoryForOrder",mid);
            }


           /* if(productOutputOrder!=null){
                productOutputOrder.setProductOutputOrderItems(productOutputOrderItems);
                JSONObject jsonObject = new JSONObject() ;
                jsonObject.put("data",productOutputOrder) ;
                jsonObject.put("eventType","updateProductInventory") ;
                super.sendMessage(jsonObject);
            }*/

        }catch (Exception e){
            logger.error("error",e);
            throw  new RuntimeException(e) ;
        }
        return  true ;


    }
    public Boolean updateStatus(OrderInfo orderInfo){
        Example example = new Example(OrderInfo.class) ;
        example.excludeProperties("status") ;
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id",orderInfo.getId()) ;
        return orderInfoMapper.updateByExampleSelective(orderInfo,example)>0 ;
    }
}
